package com.unity3d.player;

import java.util.*;
import java.lang.reflect.*;

final class ReflectionHelper
{
    protected static boolean LOG = false;
    protected static final boolean LOGV = false;
    private static a[] a;

    static {
        ReflectionHelper.a = new a[4096];
    }

    private static float a(final Class p0, final Class p1) {
        //
        // This method could not be decompiled.
        //
        // Original Bytecode:
        //
        //     1: aload_1
        //     2: invokevirtual   java/lang/Object.equals:(Ljava/lang/Object;)Z
        //     5: ifeq            10
        //     8: fconst_1
        //     9: freturn
        //    10: aload_0
        //    11: invokevirtual   java/lang/Class.isPrimitive:()Z
        //    14: ifne            50
        //    17: aload_1
        //    18: invokevirtual   java/lang/Class.isPrimitive:()Z
        //    21: ifne            50
        //    24: aload_0
        //    25: aload_1
        //    26: invokevirtual   java/lang/Class.asSubclass:(Ljava/lang/Class;)Ljava/lang/Class;
        //    29: astore_2
        //    30: aload_2
        //    31: ifnull          37
        //    34: ldc             0.5
        //    36: freturn
        //    37: aload_1
        //    38: aload_0
        //    39: invokevirtual   java/lang/Class.asSubclass:(Ljava/lang/Class;)Ljava/lang/Class;
        //    42: astore_0
        //    43: aload_0
        //    44: ifnull          50
        //    47: ldc             0.1
        //    49: freturn
        //    50: fconst_0
        //    51: freturn
        //    52: astore_2
        //    53: goto            37
        //    56: astore_0
        //    57: goto            50
        //    Exceptions:
        //  Try           Handler
        //  Start  End    Start  End    Type
        //  -----  -----  -----  -----  ------------------------------
        //  24     30     52     56     Ljava/lang/ClassCastException;
        //  37     43     56     60     Ljava/lang/ClassCastException;
        //
        // The error that occurred was:
        //
        // java.lang.IllegalStateException: Expression is linked from several locations: Label_0037:
        //     at com.strobel.decompiler.ast.Error.expressionLinkedFromMultipleLocations(Error.java:27)
        //     at com.strobel.decompiler.ast.AstOptimizer.mergeDisparateObjectInitializations(AstOptimizer.java:2596)
        //     at com.strobel.decompiler.ast.AstOptimizer.optimize(AstOptimizer.java:235)
        //     at com.strobel.decompiler.ast.AstOptimizer.optimize(AstOptimizer.java:42)
        //     at com.strobel.decompiler.languages.java.ast.AstMethodBodyBuilder.createMethodBody(AstMethodBodyBuilder.java:214)
        //     at com.strobel.decompiler.languages.java.ast.AstMethodBodyBuilder.createMethodBody(AstMethodBodyBuilder.java:99)
        //     at com.strobel.decompiler.languages.java.ast.AstBuilder.createMethodBody(AstBuilder.java:782)
        //     at com.strobel.decompiler.languages.java.ast.AstBuilder.createMethod(AstBuilder.java:675)
        //     at com.strobel.decompiler.languages.java.ast.AstBuilder.addTypeMembers(AstBuilder.java:552)
        //     at com.strobel.decompiler.languages.java.ast.AstBuilder.createTypeCore(AstBuilder.java:519)
        //     at com.strobel.decompiler.languages.java.ast.AstBuilder.createTypeNoCache(AstBuilder.java:161)
        //     at com.strobel.decompiler.languages.java.ast.AstBuilder.createType(AstBuilder.java:150)
        //     at com.strobel.decompiler.languages.java.ast.AstBuilder.addType(AstBuilder.java:125)
        //     at com.strobel.decompiler.languages.java.JavaLanguage.buildAst(JavaLanguage.java:71)
        //     at com.strobel.decompiler.languages.java.JavaLanguage.decompileType(JavaLanguage.java:59)
        //     at us.deathmarine.luyten.DecompilerLinkProvider.generateContent(DecompilerLinkProvider.java:97)
        //     at us.deathmarine.luyten.OpenFile.decompileWithNavigationLinks(OpenFile.java:494)
        //     at us.deathmarine.luyten.OpenFile.decompile(OpenFile.java:467)
        //     at us.deathmarine.luyten.Model.extractClassToTextPane(Model.java:420)
        //     at us.deathmarine.luyten.Model.openEntryByTreePath(Model.java:339)
        //     at us.deathmarine.luyten.Model$TreeListener$1.run(Model.java:266)
        //
        throw new IllegalStateException("An error occurred while decompiling this method.");
    }

    private static float a(final Class clazz, final Class[] array, final Class[] array2) {
        if (array2.length == 0) {
            return 0.1f;
        }
        int n = 0;
        int length;
        if (array == null) {
            length = 0;
        }
        else {
            length = array.length;
        }
        if (length + 1 != array2.length) {
            return 0.0f;
        }
        float n3;
        float n2 = n3 = 1.0f;
        if (array != null) {
            final int length2 = array.length;
            int n4 = 0;
            while (true) {
                n3 = n2;
                if (n >= length2) {
                    break;
                }
                n2 *= a(array[n], array2[n4]);
                ++n;
                ++n4;
            }
        }
        return n3 * a(clazz, array2[array2.length - 1]);
    }

    private static Class a(String s, final int[] array) {
        Label_0220: {
            int index = 0;
            Block_4: {
                while (array[0] < s.length()) {
                    final int n = array[0];
                    array[0] = n + 1;
                    final char char1 = s.charAt(n);
                    if (char1 != '(' && char1 != ')') {
                        if (char1 != 'L') {
                            break Label_0220;
                        }
                        index = s.indexOf(59, array[0]);
                        if (index != -1) {
                            break Block_4;
                        }
                        break Label_0220;
                    }
                }
                break Label_0220;
            }
            s = s.substring(array[0], index);
            array[0] = index + 1;
            s = s.replace('/', '.');
            try {
                return Class.forName(s);
                Label_0170: {
                    return Array.newInstance(a(s, array), 0).getClass();
                }
                // iftrue(Label_0189:, char1 != '[')
                final StringBuilder sb;
                Label_0189: {
                    sb = new StringBuilder("! parseType; ");
                }
                final char char1;
                sb.append(char1);
                sb.append(" is not known!");
                e.Log(5, sb.toString());
                return null;
                Label_0100:
                // iftrue(Label_0110:, char1 != 'I')
                return Integer.TYPE;
                Label_0120:
                // iftrue(Label_0130:, char1 != 'V')
                return Void.TYPE;
                Label_0140:
                // iftrue(Label_0150:, char1 != 'S')
                return Short.TYPE;
                // iftrue(Label_0100:, char1 != 'Z')
                return Boolean.TYPE;
                Label_0110:
                // iftrue(Label_0120:, char1 != 'F')
                return Float.TYPE;
                Label_0160:
                // iftrue(Label_0170:, char1 != 'D')
                return Double.TYPE;
                return null;
                Label_0130:
                // iftrue(Label_0140:, char1 != 'B')
                return Byte.TYPE;
                Label_0150:
                // iftrue(Label_0160:, char1 != 'J')
                return Long.TYPE;
            }
            catch (ClassNotFoundException ex) {
                return null;
            }
        }
    }

    private static void a(final a a, final Member a2) {
        a.a = a2;
        ReflectionHelper.a[a.hashCode() & ReflectionHelper.a.length - 1] = a;
    }

    private static boolean a(final a a) {
        final a a2 = ReflectionHelper.a[a.hashCode() & ReflectionHelper.a.length - 1];
        if (!a.equals(a2)) {
            return false;
        }
        a.a = a2.a;
        return true;
    }

    private static Class[] a(final String s) {
        final int[] array = { 0 };
        int n = 0;
        array[0] = 0;
        final ArrayList<Class> list = new ArrayList<Class>();
        while (array[0] < s.length()) {
            final Class a = a(s, array);
            if (a == null) {
                break;
            }
            list.add(a);
        }
        final Class[] array2 = new Class[list.size()];
        final Iterator<Class> iterator = list.iterator();
        while (iterator.hasNext()) {
            array2[n] = iterator.next();
            ++n;
        }
        return array2;
    }

    protected static Constructor getConstructorID(final Class clazz, final String s) {
        final a a = new a(clazz, "", s);
        Constructor constructor;
        if (a(a)) {
            constructor = (Constructor)a.a;
        }
        else {
            final Class[] a2 = a(s);
            float n = 0.0f;
            final Constructor[] constructors = clazz.getConstructors();
            final int length = constructors.length;
            int n2 = 0;
            Constructor constructor2 = null;
            while (true) {
                constructor = constructor2;
                if (n2 >= length) {
                    break;
                }
                constructor = constructors[n2];
                final float a3 = a(Void.TYPE, constructor.getParameterTypes(), a2);
                float n3 = n;
                if (a3 > n) {
                    if (a3 == 1.0f) {
                        break;
                    }
                    constructor2 = constructor;
                    n3 = a3;
                }
                ++n2;
                n = n3;
            }
            a(a, constructor);
        }
        if (constructor != null) {
            return constructor;
        }
        final StringBuilder sb = new StringBuilder("<init>");
        sb.append(s);
        sb.append(" in class ");
        sb.append(clazz.getName());
        throw new NoSuchMethodError(sb.toString());
    }

    protected static Field getFieldID(final Class clazz, final String s, final String s2, final boolean b) {
        Class superclass = clazz;
        final a a = new a(superclass, s, s2);
        Field field;
        if (a(a)) {
            field = (Field)a.a;
        }
        else {
            final Class[] a2 = a(s2);
            float n = 0.0f;
            Field field2 = null;
            while (true) {
                field = field2;
                if (superclass == null) {
                    break;
                }
                final Field[] declaredFields = superclass.getDeclaredFields();
                float n2;
                Field field4;
                for (int length = declaredFields.length, i = 0; i < length; ++i, n = n2, field2 = field4) {
                    final Field field3 = declaredFields[i];
                    n2 = n;
                    field4 = field2;
                    if (b == Modifier.isStatic(field3.getModifiers())) {
                        n2 = n;
                        field4 = field2;
                        if (field3.getName().compareTo(s) == 0) {
                            final float a3 = a(field3.getType(), null, a2);
                            n2 = n;
                            field4 = field2;
                            if (a3 > n) {
                                if (a3 == 1.0f) {
                                    field2 = field3;
                                    n = a3;
                                    break;
                                }
                                n2 = a3;
                                field4 = field3;
                            }
                        }
                    }
                }
                field = field2;
                if (n == 1.0f) {
                    break;
                }
                field = field2;
                if (superclass.isPrimitive()) {
                    break;
                }
                field = field2;
                if (superclass.isInterface()) {
                    break;
                }
                field = field2;
                if (superclass.equals(Object.class)) {
                    break;
                }
                field = field2;
                if (superclass.equals(Void.TYPE)) {
                    break;
                }
                superclass = superclass.getSuperclass();
            }
            a(a, field);
        }
        if (field == null) {
            String s3;
            if (b) {
                s3 = "static";
            }
            else {
                s3 = "non-static";
            }
            throw new NoSuchFieldError(String.format("no %s field with name='%s' signature='%s' in class L%s;", s3, s, s2, superclass.getName()));
        }
        return field;
    }

    protected static Method getMethodID(Class clazz, final String s, final String s2, final boolean b) {
        final a a = new a(clazz, s, s2);
        Method method;
        if (a(a)) {
            method = (Method)a.a;
        }
        else {
            final Class[] a2 = a(s2);
            float n = 0.0f;
            final Method method2 = null;
            Class superclass = clazz;
            Method method3 = method2;
            while (true) {
                method = method3;
                if (superclass == null) {
                    break;
                }
                final Method[] declaredMethods = superclass.getDeclaredMethods();
                float n2;
                Method method5;
                for (int length = declaredMethods.length, i = 0; i < length; ++i, n = n2, method3 = method5) {
                    final Method method4 = declaredMethods[i];
                    n2 = n;
                    method5 = method3;
                    if (b == Modifier.isStatic(method4.getModifiers())) {
                        n2 = n;
                        method5 = method3;
                        if (method4.getName().compareTo(s) == 0) {
                            final float a3 = a(method4.getReturnType(), method4.getParameterTypes(), a2);
                            n2 = n;
                            method5 = method3;
                            if (a3 > n) {
                                if (a3 == 1.0f) {
                                    method3 = method4;
                                    n = a3;
                                    break;
                                }
                                n2 = a3;
                                method5 = method4;
                            }
                        }
                    }
                }
                method = method3;
                if (n == 1.0f) {
                    break;
                }
                method = method3;
                if (superclass.isPrimitive()) {
                    break;
                }
                method = method3;
                if (superclass.isInterface()) {
                    break;
                }
                method = method3;
                if (superclass.equals(Object.class)) {
                    break;
                }
                method = method3;
                if (superclass.equals(Void.TYPE)) {
                    break;
                }
                superclass = superclass.getSuperclass();
            }
            a(a, method);
            clazz = superclass;
        }
        if (method == null) {
            String s3;
            if (b) {
                s3 = "static";
            }
            else {
                s3 = "non-static";
            }
            throw new NoSuchMethodError(String.format("no %s method with name='%s' signature='%s' in class L%s;", s3, s, s2, clazz.getName()));
        }
        return method;
    }

    private static native void nativeProxyFinalize(final int p0);

    private static native Object nativeProxyInvoke(final int p0, final String p1, final Object[] p2);

    protected static Object newProxyInstance(final int n, final Class clazz) {
        return newProxyInstance(n, new Class[] { clazz });
    }

    protected static Object newProxyInstance(final int n, final Class[] array) {
        return Proxy.newProxyInstance(ReflectionHelper.class.getClassLoader(), array, new InvocationHandler() {
            @Override
            protected final void finalize() {
                try {
                    nativeProxyFinalize(n);
                }
                finally {
                    super.finalize();
                }
            }

            @Override
            public final Object invoke(final Object o, final Method method, final Object[] array) {
                return nativeProxyInvoke(n, method.getName(), array);
            }
        });
    }

    private static final class a
    {
        public volatile Member a;
        private final Class b;
        private final String c;
        private final String d;
        private final int e;

        a(final Class b, final String c, final String d) {
            this.b = b;
            this.c = c;
            this.d = d;
            this.e = ((this.b.hashCode() + 527) * 31 + this.c.hashCode()) * 31 + this.d.hashCode();
        }

        @Override
        public final boolean equals(final Object o) {
            if (o == this) {
                return true;
            }
            if (o instanceof a) {
                final a a = (a)o;
                if (this.e == a.e && this.d.equals(a.d) && this.c.equals(a.c) && this.b.equals(a.b)) {
                    return true;
                }
            }
            return false;
        }

        @Override
        public final int hashCode() {
            return this.e;
        }
    }
}
